///////////////////////////////////////////////////////////////////////////////
//
// DBT86 Project : Common Files : debug.h
// Copyright (C) 2004 by Ben Hertzberg and Stanford University
// All Rights Reserved
//
// This code may not be used for any purpose without the express written
// consent of the author.  See the LICENSE.txt file for details.
//
//
// DESCRIPTION
//
// This header file contains project-wide debugging support APIs.
// Use only with CFG_DEBUG enabled.
//
// TODO: currently the UNIX debug routines are hacked out with macros.
//
///////////////////////////////////////////////////////////////////////////////

#ifndef __DEBUG_H__
#define __DEBUG_H__
#include "common.h"

extern void DbgNativeExec();

extern void DbgDebugBreak();

extern UINT DbgCpuSearchBreak;

// VC uses _DEBUG, others can config with CFG_DEBUG
// Internally, we use just "DEBUG" for conciseness
#if CFG_DEBUG
// Another (shorter) name for CFG_DEBUG
#define DEBUG 1

// used for binary search through program interpretation to find bugs (may be needed in optimized code as well)
#define CFG_DEBUG_INTERP_SEARCH 1

// To enable codegen search
#define CFG_DEBUG_CG_SEARCH 1

// To enable codegen spew
#define CFG_GEN_DEBUG 1
#define CFG_GEN_DEBUG_COND (GenDbgSearchBreak && (GenDbgSearchCtr >= GenDbgSearchCount))

// When codegen spew is enabled, it goes to debug console when this parameter is 0,
// otherwise it goes to cg_out.txt
#define CFG_GEN_DEBUG_FILE 0

// To enable execution spew
#define CFG_EXEC_DEBUG 0

// to enable exec search
#define CFG_DEBUG_EXEC_SEARCH 1

// to enable IP search (used in misc debugging)
#define CFG_DEBUG_IP_SEARCH 0
#if CFG_DEBUG_IP_SEARCH
extern IVAL DbgIPSearch;
#endif

#endif

// for optimized code, transform assertions into assumptions
#ifdef DEBUG

#  define DEBUG_BREAKPOINT DbgDebugBreak()

# if defined(_MSC_VER)
#  include <crtdbg.h>
//#  define ASSERT(e)    _ASSERTE(e)
//#  define ASSERTDBG(e) _ASSERTE(e)
#  define ASSERT(e)    DbgAssert(((e)!=0), #e, __FILE__, __LINE__)
#  define ASSERTDBG(e) DbgAssert(((e)!=0), #e, __FILE__, __LINE__)

   typedef unsigned long long DbgFileHandle;
   extern void DbgOutputStr(char* s);
   extern void DbgOutputStrPad(char* s, int pad);
   extern void DbgOutputHex(unsigned int x);
   extern DbgFileHandle DbgFileInit(char *name);
   extern void DbgFileDone(DbgFileHandle f);
   extern void DbgFileFlush(DbgFileHandle f);
   extern void DbgFileOutputStr(DbgFileHandle f, char* s);
   extern void DbgFileOutputStrPad(DbgFileHandle f, char* s, int pad);
   extern void DbgFileOutputHex(DbgFileHandle f, unsigned int x);
   extern void DbgAssert(int cond, char *s, char *fn, int line);
# else
#  include <assert.h>
#  define ASSERT(e) assert(e)
#  define ASSERTDBG(e) assert(e)
   typedef unsigned long long DbgFileHandle;
#  define DbgOutputStr(x)
#  define DbgOutputStrPad(x,y)
#  define DbgOutputHex(x)
#  define DbgFileInit(x) 0
#  define DbgFileDone(x)
#  define DbgFileFlush(x)
#  define DbgFileOutputStr(x,y)
#  define DbgFileOutputStrPad(x,y,z)
#  define DbgFileOutputHex(x,y)
#  define DbgAssert(x,y,z,w) assert(y)
# endif
#else
#ifdef LESS86
# define ASSERT(e)    ( __assume(e) )
#endif
# define ASSERTDBG(e)
# define DEBUG_BREAKPOINT
#endif

// enables expression of ASSERT(UNREACHED) to have desired effect in optimized as well as debug code
#define UNREACHED 0

#endif
